package com.cqfae.deploycentral.app.services.impl;

import com.cqfae.deploycentral.app.base.BaseConstants;
import com.cqfae.deploycentral.app.dao.entity.*;
import com.cqfae.deploycentral.app.dao.mapper.*;
import com.cqfae.deploycentral.app.services.DatePlateService;
import com.cqfae.deploycentral.app.utils.NullUtil;
import com.cqfae.deploycentral.app.utils.TimeUtil;
import com.cqfae.deploycentral.app.web.enums.DeployPercentEnum;
import com.cqfae.deploycentral.app.web.enums.ProgressColorEnum;
import com.cqfae.deploycentral.app.web.vo.DatePlatePlugInVo;
import com.cqfae.deploycentral.app.web.vo.DatePlateVo;
import com.cqfae.deploycentral.app.web.vo.WindowPlansTagVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

import static com.cqfae.deploycentral.app.base.BaseConstantCode.*;

@Service
@Transactional
public class DatePlateServiceImpl implements DatePlateService {

    @Autowired
    private RegionMapper regionMapper;
    @Autowired
    private AppInfoMapper appInfoMapper;
    @Autowired
    private TimeUtil timeUtil;
    @Autowired
    private WindowPlansMapper windowPlansMapper;
    @Autowired
    private ReportInfoTagMapper reportInfoTagMapper;
    @Autowired
    private WindowPlansTagMapper windowPlansTagMapper;
    @Autowired
    private ApproveDocumentMapper approveDocumentMapper;
    @Autowired
    private ReportTestLinkMapper reportTestLinkMapper;

    private static final String PROJECTNAME = "projectName";

    private static final String DEPLOYSTATUS = "deployStatus";

    @Override
    public List<Map<String,Object>> displayDeployCentral(){
        List<Map<String,Object>> expectList = new CopyOnWriteArrayList<>();
        List<Map<String,String>> sonList = new CopyOnWriteArrayList<>();
        //子数据链
        Region region = new Region();
        region.setLevelCode("1000");
        List<Region> regionList = regionMapper.select(region);
        Map<String,Object> paramMap = new HashMap<>();
        for(Region info:regionList){
            Map<String,String> paramMap1 = new HashMap<>();
            paramMap1.put("name",info.getName());
            paramMap1.put("value",info.getCode());
            sonList.add(paramMap1);
        }
        Object o = "重庆";
        paramMap.put("name",o);
        paramMap.put("value",sonList);
        expectList.add(paramMap);
        return expectList;
    }

    @Override
    public DatePlateVo displayDatePlateVo(){
        //Step Pre 处理之前的V204 没有JIRA版本号的问题
        ApproveDocument approveDocument = new ApproveDocument();
        approveDocument.setJiraVersionId(Long.parseLong("0"));
        List<ApproveDocument> approveDocuments = approveDocumentMapper.select(approveDocument);
        if(!approveDocuments.isEmpty()){
            for(ApproveDocument approveInfo:approveDocuments){
                ReportTestLink reportTestLink = new ReportTestLink();
                reportTestLink.setReportCode(approveInfo.getAppId().toString());
                List<ReportTestLink> reportTestLinks = reportTestLinkMapper.select(reportTestLink);
                approveInfo.setJiraVersionId(reportTestLinks.get(0).getVersionId());
                approveInfo.setJiraVersionName(reportTestLinks.get(0).getVersionName());
                approveDocumentMapper.updateByPrimaryKeySelective(approveInfo);
            }
        }
        //Step1 总体部署的概述
        DatePlateVo datePlateVo = new DatePlateVo();
        List<Map<String,Object>> projectInfos = appInfoMapper.countProjectInfo();
        //项目的组别数
        datePlateVo.setProjectTotal(projectInfos.size());
        //所有的项目总数
        AppInfo appInfo = new AppInfo();
        int appCount = appInfoMapper.selectCount(appInfo);
        datePlateVo.setAppTotal(appCount);
        //所有未部署的应用
        WindowPlansTag windowPlansTag = new WindowPlansTag();
        windowPlansTag.setDeployStatus(DEPLOY_STATUS_NOBUILD);
        datePlateVo.setUnDeployTotal(windowPlansTagMapper.selectCount(windowPlansTag));

        //部署失败的数量
        List<Integer> deployStatus = new ArrayList<>();
        deployStatus.add(DEPLOY_STATUS_FAIL);
        deployStatus.add(JENKINS_STATUS_GIT_FAIL);
        deployStatus.add(JENKINS_STATUS_BUILD_FAIL);
        deployStatus.add(JENKINS_STATUS_INPUT_FAIL);
        deployStatus.add(JENKINS_STATUS_OUTPUT_FAIL);
        deployStatus.add(JENKINS_STATUS_DEPLOY_FAIL);
        deployStatus.add(JENKINS_STATUS_CHECK_FAIL);
        Example example = new Example(WindowPlansTag.class);

        example.createCriteria().andIn(DEPLOYSTATUS , deployStatus);
        datePlateVo.setDeployFailTotal(windowPlansTagMapper.selectCountByExample(example));

        //Step2 扇形图插件
        datePlateVo = packDistribution(datePlateVo,projectInfos);

        //Step3 柱状图插件&趋势图插件
        datePlateVo = packWeekDateDeploy(datePlateVo);

        //Step4 拼接窗口的查询时间
        datePlateVo.setBeginDate(Integer.parseInt(timeUtil.getCurrentMonday()));
        datePlateVo.setEndDate(Integer.parseInt(timeUtil.getPreviousSunday()));
        datePlateVo.setDeployStatus(DEPLOY_STATUS_WAITING);
        return datePlateVo;
    }
    //Server To  displayDatePlateVo() 扇形图插件
    public DatePlateVo packDistribution(DatePlateVo datePlateVo,List<Map<String,Object>> projectInfos){
        //Step 1 在扇形图中写入项目组信息
        List<DatePlatePlugInVo> distributionPlugIns = new CopyOnWriteArrayList<>();
        for(Map<String,Object > project:projectInfos){
            DatePlatePlugInVo datePlatePlugInVo = new DatePlatePlugInVo();
            String projectName = project.get(PROJECTNAME).toString();
            datePlatePlugInVo.setProjectName(projectName);
            datePlatePlugInVo.setProjectPrivate(Integer.parseInt(project.get("projectPrivate").toString()));
            datePlatePlugInVo.setProjectCurrentDeploy(getTagInfo(projectName,true));
            distributionPlugIns.add(datePlatePlugInVo);
        }
        datePlateVo.setDistributionPlugIn(distributionPlugIns);
        return datePlateVo;
    }
    //Server To displayDatePlateVo() 柱状图插件&趋势图插件
    public DatePlateVo packWeekDateDeploy(DatePlateVo datePlateVo){
        List<DatePlatePlugInVo> weekDateDeployPlugIn = new CopyOnWriteArrayList<>();
        List<String> currentWeek = timeUtil.getCurrentWeek();
        for(int i=0;i<currentWeek.size();i++){
            DatePlatePlugInVo datePlatePlugInVo = new DatePlatePlugInVo();
            datePlatePlugInVo.setCurrentWeekDate(currentWeek.get(i).substring(5,10));
            datePlatePlugInVo.setCurrentDateDeploy(getTagInfo(currentWeek.get(i),false));
            weekDateDeployPlugIn.add(datePlatePlugInVo);
        }
        datePlateVo.setWeekDateDeployPlugIn(weekDateDeployPlugIn);
        return datePlateVo;
    }
    //Server To displayDatePlateVo() 查询每一个项目组本周需要部署的数量
    public int getTagInfo(String projectNameOrDate,boolean flag){
        Example example = new Example(WindowPlans.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andBetween("windowDate", Integer.parseInt(timeUtil.getCurrentMonday()), Integer.parseInt(timeUtil.getPreviousSunday()));
        List<WindowPlans> windowPlanList = windowPlansMapper.selectByExample(example);
        List<Long> windowPlansIdList = new ArrayList<>();
        for (WindowPlans windowPlans : windowPlanList) {
            windowPlansIdList.add(windowPlans.getId());
        }

        int countNum = 0;
        if (windowPlansIdList.isEmpty()) {
            return countNum;
        }

        Example exampleTag = new Example(WindowPlansTag.class);
        exampleTag.createCriteria().andEqualTo(DEPLOYSTATUS , DEPLOY_STATUS_NOBUILD).andIn("windowPlansId", windowPlansIdList);
        List<WindowPlansTag> windowPlansTags = windowPlansTagMapper.selectByExample(exampleTag);

        for(WindowPlansTag tagInfo:windowPlansTags){
            if(flag) {
                ReportInfoTag reportInfoTag = new ReportInfoTag();
                reportInfoTag.setId(tagInfo.getReportTagId());
                reportInfoTag = reportInfoTagMapper.selectOne(reportInfoTag);
                AppInfo appInfo = new AppInfo();
                appInfo.setAppName(reportInfoTag.getAppName());
                appInfo = appInfoMapper.selectOne(appInfo);
                if (projectNameOrDate.equals(appInfo.getProjectName())) {
                    countNum += 1;
                }
            }else{
                WindowPlans windowPlans = new WindowPlans();
                windowPlans.setId(tagInfo.getWindowPlansId());
                windowPlans = windowPlansMapper.selectOne(windowPlans);
                if(Integer.parseInt(projectNameOrDate.replace("-","")) == windowPlans.getWindowDate()){
                    countNum += 1;
                }
            }
        }
        return countNum;
    }


    @Override
    public List<WindowPlansTagVo> queryProjectTagInfo(String projectName){
        //Step1 首先排除的是窗口计划信息中筛选应用信息
        Example example = new Example(WindowPlans.class);
        Example.Criteria criteria = example.createCriteria();
        if(!"unDeployTotal,deployFailTotal".contains(projectName)){
            criteria.andBetween("windowDate", Integer.parseInt(timeUtil.getCurrentMonday()), Integer.parseInt(timeUtil.getPreviousSunday()));
        }
        List<WindowPlans> windowPlanList = windowPlansMapper.selectByExample(example);
        //Step2 通过测试报告号找到符合条件的tag信息
        List<WindowPlansTagVo> windowPlansTagVos = temp(windowPlanList,projectName);

        //Step 3 获取tag的窗口id和当前状态
        List<WindowPlansTagVo> windowPlansTagVosEnd = new CopyOnWriteArrayList<>();
        for(WindowPlansTagVo windowPlansTagVo:windowPlansTagVos){
            WindowPlansTagVo tagVo = new WindowPlansTagVo();
            BeanUtils.copyProperties(windowPlansTagVo,tagVo);
            tagVo.setDeployStatus(windowPlansTagVo.getDeployStatus());
            tagVo.setWindowPlansId(windowPlansTagVo.getWindowPlansId());
            tagVo.setProgress(DeployPercentEnum.value(windowPlansTagVo.getDeployStatus()));
            tagVo.setProgressColor(ProgressColorEnum.value(windowPlansTagVo.getDeployStatus()));
            tagVo.setDeployStatusName(BaseConstants.getConstantsCodeMap().get(String.valueOf(windowPlansTagVo.getDeployStatus())));
            windowPlansTagVosEnd.add(tagVo);
        }
        return windowPlansTagVosEnd;
    }

    public List<WindowPlansTagVo> temp(List<WindowPlans> windowPlanList,String projectName){
        List<WindowPlansTagVo> windowPlansTagVos = new CopyOnWriteArrayList<>();
        if(windowPlanList.isEmpty()){
            return windowPlansTagVos;
        }
        for(WindowPlans windowPlan:windowPlanList){
            Example example = new Example(WindowPlansTag.class);
            Example.Criteria ca = example.createCriteria();
            if("deployFailTotal".equals(projectName)){
                List<Integer> deployStatus = new ArrayList<>();
                deployStatus.add(DEPLOY_STATUS_FAIL);
                deployStatus.add(JENKINS_STATUS_GIT_FAIL);
                deployStatus.add(JENKINS_STATUS_BUILD_FAIL);
                deployStatus.add(JENKINS_STATUS_INPUT_FAIL);
                deployStatus.add(JENKINS_STATUS_OUTPUT_FAIL);
                deployStatus.add(JENKINS_STATUS_DEPLOY_FAIL);
                deployStatus.add(JENKINS_STATUS_CHECK_FAIL);
                ca.andIn(DEPLOYSTATUS, deployStatus);
            }else{
                ca.andEqualTo(DEPLOYSTATUS,DEPLOY_STATUS_NOBUILD);
            }
            ca.andEqualTo("windowPlansId",windowPlan.getId());
            List<WindowPlansTag> windowPlansTags = windowPlansTagMapper.selectByExample(example);

            if(!windowPlansTags.isEmpty()){
                windowPlansTagVos = getReportInfo(windowPlansTagVos,windowPlansTags,projectName);
            }
        }
        return windowPlansTagVos;
    }

    public List<WindowPlansTagVo> getReportInfo(List<WindowPlansTagVo> windowPlansTagVos,
                                                List<WindowPlansTag> windowPlansTags,String projectName){
        for(WindowPlansTag windowPlansTag1:windowPlansTags){
            WindowPlansTagVo windowPlansTagVo = new WindowPlansTagVo();
            ReportInfoTag reportTag = new ReportInfoTag();
            reportTag.setId(windowPlansTag1.getReportTagId());
            reportTag = reportInfoTagMapper.selectOne(reportTag);
            AppInfo appInfo = new AppInfo();
            appInfo.setAppName(reportTag.getAppName());
            appInfo = appInfoMapper.selectOne(appInfo);
            if(projectName.equals(appInfo.getProjectName()) || "unDeployTotal,deployFailTotal".contains(projectName)){
                windowPlansTagVo.setReportTagId(reportTag.getId());
                windowPlansTagVo.setAppName(reportTag.getAppName());
                windowPlansTagVo.setTagInfo(reportTag.getTagInfo());
                windowPlansTagVo.setReportCode(reportTag.getReportCode());
                windowPlansTagVo.setLevel(reportTag.getLevel());
                windowPlansTagVo.setDeployStatus(windowPlansTag1.getDeployStatus());
            }
            if(NullUtil.isNotEmpty(windowPlansTagVo.getReportTagId())){
                windowPlansTagVos.add(windowPlansTagVo);
            }
        }
        return windowPlansTagVos;
    }
}
